package ch.subgate.spritestudio.types;

import ch.subgate.spritestudio.constants.Constants;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Environment;

public class Sprite {
	
	/** Sprite name */
	public String mFileName;
	
	/** Project name */
	public String mProjectName;
	
	/** Total sprite width */
	public int mTotalWidth;
	
	/** Frame width */
	public int mFrameWidth;
	
	/** Total sprite height */
	public int mHeight;
	
	/** Number of frames */
	public int mFrames;
	
	/** Animation speed, frames per second */
	public int mFps;
	
	/** Bitmap data */
	private Bitmap mBitmap;
	
	/** Rectangle designating the current frame */
	private Rect mSource;
	
	private int mCurrentFrame;
	
	public static boolean isValidFileName(String fileName) {
		for (int i = 0; i < fileName.length(); i++) {
			if (Constants.ILLEGAL_CHARACTERS.indexOf(fileName.charAt(i)) >= 0) {
				return false;
			}
		}
		return true;
	}
	
	public Sprite(
			String fileName, String projectName, int frames, int fps) {
		mFileName = fileName;
		mProjectName = projectName;
		mTotalWidth = 0;
		mFrameWidth = 0;
		mHeight = 0;
		mFrames = frames;
		mFps = fps;
		mBitmap = null;
		mSource = new Rect();
		mCurrentFrame = 0;
	}
	
	/** Standard constructor for SpriteStudio standard version */
	public Sprite(String fileName, String projectName) {
		mFileName = fileName;
		mProjectName = projectName;
		mTotalWidth = 0;
		mFrameWidth = 0;
		mHeight = 0;
		mFrames = 1;
		mFps = 1;
		mBitmap = null;
		mSource = new Rect();
		mCurrentFrame = -1;
	}
	
	/** Drawing function for drawing a specific frame to a given position on a canvas */
	public void drawFrame(int frame, Canvas canvas, RectF dest) {
		if (mBitmap != null) {
			if (!mBitmap.isRecycled()) {
				if (mCurrentFrame != frame) {
					mCurrentFrame = frame;
					mSource.set(
							mCurrentFrame * mFrameWidth, 0,
							(mCurrentFrame + 1) * mFrameWidth, mHeight);
				}
				canvas.drawBitmap(mBitmap, mSource, dest, null);
			}
		}
	}
	
	/** Standard getter for mBitmap */
	public Bitmap getBitmap() {
		return mBitmap;
	}
	
	/** Standard setter for mBitmap */
	public void setBitmap(Bitmap bitmap, int frames) {
		if (mBitmap != null) {
			if (!mBitmap.isRecycled()) {
				mBitmap.recycle();
			}
			mBitmap = null;
		}
		
		mBitmap = bitmap;
		if (mBitmap != null && frames > 0) {
			mTotalWidth = bitmap.getWidth();
			mHeight = bitmap.getHeight();
			mFrames = frames;
			mFrameWidth = mTotalWidth / mFrames;
		}
		else {
			mTotalWidth = 0;
			mHeight = 0;
		}
	}
	
	/**
	 * Standard setter for the picture
	 */
	public void setBitmap(int width, int height, int[] pixels, int frames) {
		if (pixels != null) {
			if (pixels.length == width * height) {
				//Free old bitmap data if necessary
				if (mBitmap != null) {
					if (!mBitmap.isRecycled()) {
						mBitmap.recycle();
					}
					mBitmap = null;
				}
				
				//Create new bitmap from given dimensions
				mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
				
				//Set the pixels
				mBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
				
				mTotalWidth = width;
				mHeight = height;
				mFrames = frames;
				mFrameWidth = mTotalWidth / mFrames;
			}
		}
	}
	
	public String getSpritePath() {
		return Environment.getExternalStorageDirectory()
				+ "/" + Constants.DEFAULT_MAIN_DIR
				+ "/" + mProjectName
				+ "/" + mFileName;
	}
	
	public void recycle() {
		if (mBitmap != null) {
			if (!mBitmap.isRecycled()) {
				mBitmap.recycle();
			}
			mBitmap = null;
		}
	}
	
	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		if (mBitmap != null) {
			if (!mBitmap.isRecycled()) {
				mBitmap.recycle();
			}
			mBitmap = null;
		}
	}
}
